module zl_2346_4(cin,clk,s,datain,wt,sel,en,overflow,codeout,segsel);
input cin, clk; //进位信号 时钟信号
input [2:0]s; //控制运算类型信号
input [3:0]datain; //输入的数据
input wt,sel,en; //wt：控制写入信号 sel：控制写入A或B en:控制输入前4位or后4位
output reg overflow; //溢出信号
output reg[7:0] codeout; //七段译码器
output reg[2:0] segsel; //八位数码管

reg [7:0] A,B; // A,B寄存器
reg [8:0] a,b,R; //双符号位a,b寄存器; R:结果
reg [7:0]D; //输入的数据
reg [3:0]data;//显示的数据

always @(posedge clk)
begin 
  if(wt)
  begin 
    //en为1写入前4高位，为0写入后4低位
    if(en) D[7:4]=datain;
	 else D[3:0]=datain;
	 //sel为1写入A，为0写入B
	 if(sel) A=D;
	 else B=D;
	 //扩充为双符号位补码
	 a[7:0]=A;
	 a[8]=a[7];
	 b[7:0]=B;
	 b[8]=b[7];
  end 
end 

//ALU
always @(posedge clk)
begin 
  case(s)
    3'b000:begin R=8'h0;overflow=0;end //清零
	 3'b001:begin R=A&B;overflow=0;end //逻辑乘
	 3'b010:begin R=A|B;overflow=0;end //逻辑加
	 3'b011:begin R=A^B;overflow=0;end //逻辑异或
	 3'b100: //算数加
	   begin  
			R=a+b+cin;
			if(R[8]==R[7])
				overflow=0;
			else
				overflow=1;
		end
    3'b101:begin R=A<<1;overflow=0;end //逻辑左移
	 3'b110:begin R=A>>1;overflow=0;end //逻辑右移
	 3'b111: //算术右移
	   begin 
		  R=A>>1;
		  R[7]=R[6];
		  overflow=0;
		end
  endcase

  		//轮流显示8位数码管
  segsel=segsel+1;
    if(segsel>=8)
	   segsel<=0;		
	   case(segsel)			
			3'd0:data=A[7:4];
			3'd1:data=A[3:0];
			3'd2:data=B[7:4];
			3'd3:data=B[3:0];
			3'd4:data=0;
			3'd5:data=0;
			3'd6:data=R[7:4];
			3'd7:data=R[3:0];
		endcase
		
		//数码管显示
		case(data)
			4'h0: codeout=8'h3F;
			4'h1: codeout=8'h06;
			4'h2: codeout=8'h5B;
			4'h3: codeout=8'h4F;
			4'h4: codeout=8'h66;
			4'h5: codeout=8'h6D;
			4'h6: codeout=8'h7D;
			4'h7: codeout=8'h07;
			4'h8: codeout=8'h7F;
			4'h9: codeout=8'h6F;
			4'hA: codeout=8'h77;
			4'hB: codeout=8'h7C;
			4'hC: codeout=8'h39;
			4'hD: codeout=8'h5E;
			4'hE: codeout=8'h79;
			4'hF: codeout=8'h71;
			default: codeout=8'h00;
		endcase

	end
endmodule


